package com.flipdf.viewer.excel;

import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.poifs.filesystem.POIFSFileSystem;

public class Excel {

	private String filePath;
	private HSSFWorkbook workbook;
	private List<Sheet> sheets;
	private List<Row> rows;
	private int currSheetNo = -1;

	public Excel(String filePath) throws FileNotFoundException, IOException {
		this.filePath = filePath;
		open();
	}

	public void open() throws FileNotFoundException, IOException {
		POIFSFileSystem fs = null;
		fs = new POIFSFileSystem(new FileInputStream(filePath));
		workbook = new HSSFWorkbook(fs);
	}

	public List<Sheet> getSheets() {
		if (sheets == null) {
			sheets = new ArrayList<Sheet>();
			int n = workbook.getNumberOfSheets();
			for (int i = 0; i < n; i++) {
				Sheet sheet = new Sheet(i, workbook.getSheetName(i));
				sheets.add(sheet);
			}
		}
		return sheets;
	}

	public List<Row> getRows(int sheetNo) {
		if (rows == null) {
			rows = new ArrayList<Row>();
			HSSFSheet sheet = workbook.getSheetAt(sheetNo);
			currSheetNo = sheetNo;
			iterRows(sheet);
		} else if (currSheetNo != sheetNo) {
			HSSFSheet sheet = workbook.getSheetAt(sheetNo);
			currSheetNo = sheetNo;
			iterRows(sheet);
		}
		return rows;
	}

	private void iterRows(HSSFSheet sheet) {
		for (Iterator rit = sheet.rowIterator(); rit.hasNext();) {
			Row rowData = new Row();
			HSSFRow row = (HSSFRow) rit.next();
			for (Iterator cit = row.cellIterator(); cit.hasNext();) {
				HSSFCell cell = (HSSFCell) cit.next();
				if (cell.getCellType() == HSSFCell.CELL_TYPE_STRING) {
					rowData.addCell(cell.getRichStringCellValue().getString());
				} else if (cell.getCellType() == HSSFCell.CELL_TYPE_NUMERIC) {
					rowData.addCell(cell.getNumericCellValue() + "");
				}
			}
			this.rows.add(rowData);
		}
	}

	public static class Sheet {
		int index;
		String name;

		public Sheet(int index, String name) {
			this.index = index;
			this.name = name;
		}

		public int getIndex() {
			return index;
		}

		public String getName() {
			return name;
		}
	}

	public static class Row {
		List<String> rowData;

		public Row() {
			this.rowData = new ArrayList<String>();
		}

		public void addCell(String cell) {
			rowData.add(cell);
		}

		public List<String> getRowData() {
			return rowData;
		}
	}

}
